package com.homepage.web.rest;

import com.homepage.repository.CompanyRepository;
import com.homepage.service.CompanyService;
import com.homepage.service.dto.CompanyDTO;
import com.homepage.service.dto.CompanyWithRelationInfoDTO;
import com.homepage.util.HeaderUtil;
import com.homepage.util.ResponseUtil;
import com.homepage.web.rest.errors.BadRequestAlertException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Objects;
import java.util.Optional;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;


/**
 * REST controller for managing {@link com.homepage.domain.Company}.
 */
@RestController
@RequestMapping("/company")
public class CompanyResource {

    private final Logger log = LoggerFactory.getLogger(CompanyResource.class);

    private static final String ENTITY_NAME = "company";

    @Value("${common.clientApp.name}")
    private String applicationName;

    private final CompanyService companyService;

    private final CompanyRepository companyRepository;

    public CompanyResource(CompanyService companyService, CompanyRepository companyRepository) {
        this.companyService = companyService;
        this.companyRepository = companyRepository;
    }
    /**
     * {@code PUT  /companies/:id} : Updates an existing company.
     *
     * @param companyDTO the companyDTO to update.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated companyDTO,
     * or with status {@code 400 (Bad Request)} if the companyDTO is not valid,
     * or with status {@code 500 (Internal Server Error)} if the companyDTO couldn't be updated.
     * @throws URISyntaxException if the Location URI syntax is incorrect.
     */
    @PutMapping("/{companyName}")
    public ResponseEntity<CompanyDTO> createCompany(@Valid @RequestBody CompanyDTO companyDTO,
                                                    @PathVariable String companyName) throws URISyntaxException {
        log.debug("REST request to save Company : {}", companyDTO);
        companyDTO.setId(companyName);
        CompanyDTO result = companyService.save(companyDTO);
        return ResponseEntity
                .created(new URI("/api/" + companyName))
                .headers(HeaderUtil.createEntityCreationAlert(applicationName, true, ENTITY_NAME, companyDTO.getId()))
                .body(result);
    }


    /**
     * {@code PATCH  /companies/:companyName} : Partial updates given fields of an existing company, field will ignore if it is null
     *
     * @param companyName the name of the companyDTO to save.
     * @param companyDTO the companyDTO to update.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated companyDTO,
     * or with status {@code 400 (Bad Request)} if the companyDTO is not valid,
     * or with status {@code 404 (Not Found)} if the companyDTO is not found,
     * or with status {@code 500 (Internal Server Error)} if the companyDTO couldn't be updated.
     * @throws URISyntaxException if the Location URI syntax is incorrect.
     */
    @PatchMapping(value = "/{companyName}", consumes = { "application/json", "application/merge-patch+json" })
    public ResponseEntity<CompanyDTO> partialUpdateCompany(
            @PathVariable(value = "companyName", required = false) final String companyName,
            @NotNull @RequestBody CompanyDTO companyDTO
    ) throws URISyntaxException {
        companyDTO.setId(companyName);
        log.debug("REST request to partial update Company partially : {}, {}", companyName, companyDTO);
        if (!Objects.equals(companyName, companyDTO.getId())) {
            throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid");
        }

        if (!companyRepository.existsById(companyName)) {
            throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound");
        }

        Optional<CompanyDTO> result = companyService.partialUpdate(companyDTO);

        return ResponseUtil.wrapOrNotFound(
                result,
                HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, companyDTO.getId())
        );
    }

    /**
     * {@code GET  /companies/:id} : get the "id" company.
     *
     * @param companyName the id of the companyDTO to retrieve.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the companyDTO, or with status {@code 404 (Not Found)}.
     */
    @GetMapping("/{companyName}")
    public ResponseEntity<CompanyDTO> getCompany(@PathVariable String companyName) {
        log.debug("REST request to get Company : {}", companyName);
        Optional<CompanyDTO> companyDTO = companyService.findOne(companyName);
        return ResponseUtil.wrapOrNotFound(companyDTO);
    }

    @GetMapping("/{companyName}/all-info")
    public ResponseEntity<CompanyWithRelationInfoDTO> getCompanyWithRelationInfo(@PathVariable String companyName) {
        log.debug("REST request to get Company : {}", companyName);
        Optional<CompanyWithRelationInfoDTO> companyDTO = companyService.findOneWithRelationInfo(companyName);
        return ResponseUtil.wrapOrNotFound(companyDTO);
    }

    /**
     * {@code DELETE  /companies/:id} : delete the "id" company.
     *
     * @param companyName the id of the companyDTO to delete.
     * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}.
     */
    @DeleteMapping("/{companyName}")
    public ResponseEntity<Void> deleteCompany(@PathVariable String companyName) {
        log.debug("REST request to delete Company : {}", companyName);
        companyService.delete(companyName);
        return ResponseEntity.noContent().headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, companyName)).build();
    }
}
